#encoding: utf-8
'''
Created on 2012-4-9

@author: huangjacky
@copyright: TeamV - Group : WhutOJ
对网页端发送过来的通过校验和的数据进行解析
'''
from pyojRequest import PyOJRequest
from pyojExecutor import PyOJExecutor
from pyojUtils import hexchar2int

class PyOJParserWeb(object):
    '''
    这个类是对网页端发送的数据进行解析
    '''
    def __init__(self):
        object.__init__(self)
        self.__buf = [] # 缓存数据
        self.__checksum = 0 # 校验和
        self.__parsestate = 0 # 当前解析的状态,0:解析标示头,1解析内容
        self.__headeridx = 0 # 开始标识符 解析的序号,0-@,1-O,2-J
        #@todo: 将Executor 模型改成线程池，以便提高工作效率
        self.__executor = PyOJExecutor() # 执行线程的启动者。 
    
    @property
    def executor(self):
        return self.__executor
    
    @property
    def checksum(self):
        return self.__checksum
    
    @property
    def parsestate(self):
        return self.__parsestate
    
    @property
    def headeridx(self):
        return self.__headeridx
        
    def clear(self):
        self.__checksum = 0
        self.__parsestate = 0
        self.__headeridx = 0
        del self.__buf[0:]
    
    def parse(self, data):
        for b in data:
            if b == '\0': # 数据结束
                if self.__parsestate == 1: #　正好在解析内容
                    # 服务端发送过来的校验和
                    ichecksum = hexchar2int(self.__buf[-1])
                    ichecksum += hexchar2int(self.__buf[-2]) << 4
                    ichecksum += hexchar2int(self.__buf[-3]) << 8
                    ichecksum += hexchar2int(self.__buf[-4]) << 12
                    # 计算本地端收到的校验和
                    self.__checksum -= ord(self.__buf[-1])
                    self.__checksum -= ord(self.__buf[-2])
                    self.__checksum -= ord(self.__buf[-3])
                    self.__checksum -= ord(self.__buf[-4])
                    if ichecksum == self.__checksum: # 如果校验和一样的话
                        # 删除校验和部分
                        del self.__buf[-6:]
                        #执行解析器
                        request = PyOJRequest.parse(''.join(self.__buf).strip())
                        if request != None: # 如果解析成功那么就执行
                            # 将数据放入到一个执行队列中去，队列中的数据再怎么执行看策略了
                            self.executor.execute(request)
                # 清空已有的数据
                self.clear()    
            else:# 计算校验和并缓存到缓冲区
                if self.__parsestate == 1: # 计算内容
                    self.__buf.append(b)
                    if b != '\r' and b != '\n':
                        self.__checksum += ord(b)
                    if len(self.__buf) > 1024: # 如果缓冲区还没有结果，就清空缓冲区
                        self.clear()
                else: # 正在解析头部
                    if self.__headeridx == 0 and b == '@':
                        self.__headeridx += 1
                    elif self.__headeridx == 1 and b == 'O':
                        self.__headeridx += 1
                    elif self.__headeridx == 2 and b == 'J':
                        self.__parsestate = 1
                        # 复制数据
                        self.__buf.extend(['@', 'O', 'J'])
                        self.__checksum = 64 + 79 + 74
                    else:
                        self.__headeridx = 0
                        
